package cn.wongshu.student.config;


import cn.wongshu.student.filter.CustomAuthenticationFilter;
import cn.wongshu.student.pojo.Result;
import cn.wongshu.student.pojo.StatusCode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.AccessDeniedException;


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().withUser("zhangsan").password("$2a$10$2O4EwLrrFPEboTfDOtC0F.RpUMk.3q3KvBHRx7XXKUMLBGjOOBs8q").roles("admin");
    }




    @Override
    protected void configure(HttpSecurity http) throws Exception {

      /*  http.authorizeRequests().antMatchers("/hello")
                .hasRole("user").antMatchers("admin")
                .hasRole("admin")
                .antMatchers(HttpMethod.POST,"/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(new JwtLogInFilter("/login",authenticationManager()),UsernamePasswordAuthenticationFilter.class )
                .addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class).csrf().disable();
*/

      //json方式
        http.authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login_p.html")
                .loginProcessingUrl("/doLogin")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll()
                .and()
                .csrf()
                .disable();

        http.addFilterAt(customAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class);








       /* http.
                authorizeRequests().antMatchers("/hello1111").hasRole("admin")
                .anyRequest().authenticated()
                .and().formLogin().loginPage("/login_p.html")
                .loginProcessingUrl("/doLogin")
                .usernameParameter("username")
                .passwordParameter("password")
                .permitAll().successHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                PrintWriter writer = httpServletResponse.getWriter();
                Result result = new Result(true, StatusCode.Ok, "登入成功");
                writer.write(new ObjectMapper().writeValueAsString(result));
                writer.flush();
                writer.close();
            }
        }).failureHandler(new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                PrintWriter writer = httpServletResponse.getWriter();
                Result result = new Result(false, StatusCode.ERROR, "账号或者密码不正确");
                writer.write(new ObjectMapper().writeValueAsString(result));
                writer.flush();
                writer.close();
            }
        })
                .permitAll()
                .and().csrf().disable();*/



    }


    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/login_p.html").and().ignoring()
                .antMatchers("/index.html")
                .and().ignoring().antMatchers("/css/**")
                .and().ignoring().antMatchers("/js/**")
                .and().ignoring().antMatchers("/plugins/**")
                .and().ignoring().antMatchers("/doLogin")
                .and().ignoring().antMatchers("/login/test");
    }


    @Bean
    CustomAuthenticationFilter customAuthenticationFilter() throws Exception {

        CustomAuthenticationFilter customAuthenticationFilter = new CustomAuthenticationFilter();
        customAuthenticationFilter.setAuthenticationSuccessHandler(new AuthenticationSuccessHandler() {
            @Override
            public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
                PrintWriter writer = httpServletResponse.getWriter();
                Result result = new Result(true,StatusCode.Ok,"登入成功");
                ObjectMapper mapper = new ObjectMapper();
                writer.write(mapper.writeValueAsString(result));
                writer.flush();
                writer.close();

            }
        });

        customAuthenticationFilter.setFilterProcessesUrl("/doLogin");
        customAuthenticationFilter.setAuthenticationFailureHandler(new AuthenticationFailureHandler() {
            @Override
            public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
                PrintWriter writer = httpServletResponse.getWriter();
                Result result = new Result(false, StatusCode.ERROR, "登入失败");
                ObjectMapper objectMapper = new ObjectMapper();
                writer.write(objectMapper.writeValueAsString(result));
                writer.flush();
                writer.close();

            }
        });
        customAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
        return customAuthenticationFilter;
    }



}
